﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime;
using System.Text;
using Imgur.Net.Auth;
using NUnit.Framework;
using TestableHttpWebResponse;

namespace Imgur.Net.Test.ImageProvider
{
    [TestFixture]
    public class UploadImageTests
    {
        private const string clientId = "b56c4ebcd84a2c5";
        private const string clientSecret = "5b83ef6e0100a5a8544cc03f2e49c470d7f7cb2f";

        private const string baseTestUriTemplate = "test://api.imgur.com/3/image";
        //private const string baseTestUriTemplate = "https://api.imgur.com/3/image";
        
        [TestFixtureSetUp]
        public void TestFixtureSetup()
        {
            WebRequest.RegisterPrefix("test", TestableWebRequestCreateFactory.GetFactory());
        }

        [Test]
        public void TestUploadImage()
        {
            ImgurAuthProvider authProvider = new AnonymousAuthenticationProvider(clientId);
            var imgProvider = new DefaultImageProvider(authProvider,
                baseTestUriTemplate);
            //var imgProvider = new DefaultImageProvider(authProvider.GetAuthorizationContext());

            var expectedRequest = new TestableWebRequest(new Uri(baseTestUriTemplate));
            expectedRequest.EnqueueResponse(HttpStatusCode.OK, "Success",
                ResourceLoader.GetResourceText("Resources/ImageProvider/ImageModel.upload.json"), false);
            TestableWebRequestCreateFactory.GetFactory().AddRequest(expectedRequest);


            byte[] data = ResourceLoader.GetResourceBytes("Resources/smiley-face.jpg");
            ImageInfo info = imgProvider.UploadImage( data, "Test Title", "test Description");
            
            Assert.IsNotNull(info);

            Assert.AreEqual("YXZlrwD", info.Id);
            Assert.AreEqual("Test Title", info.Title);
            Assert.AreEqual("test Description", info.Description);
            Assert.AreEqual(new DateTime(2014, 10, 15, 14, 55, 38), info.TimeStamp);
            Assert.AreEqual("image/jpeg", info.MimeType);
            Assert.AreEqual(false, info.IsAnimated);
            Assert.AreEqual(1600, info.Width);
            Assert.AreEqual(1200, info.Height);
            Assert.AreEqual(85201, info.FileSize);
            Assert.AreEqual(0, info.Views);
            Assert.AreEqual(0, info.Bandwidth);
            Assert.AreEqual(false, info.IsFavorite);
            Assert.IsNull(info.IsNSFW);
            Assert.IsNull(info.Section);
            Assert.IsNull(info.AccountUrl);
            Assert.AreEqual("R1oNYzqdLz3Q1Yw", info.DeleteHash);
            Assert.AreEqual("http://i.imgur.com/YXZlrwD.jpg", info.Link);
        }

        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void TestEmptyDataUploadImage()
        {
            ImgurAuthProvider authProvider = new AnonymousAuthenticationProvider(clientId);
            var imgProvider = new DefaultImageProvider(authProvider,
                baseTestUriTemplate);
            //var imgProvider = new DefaultImageProvider(authProvider.GetAuthorizationContext());

            var expectedRequest = new TestableWebRequest(new Uri(baseTestUriTemplate));
            expectedRequest.EnqueueResponse(HttpStatusCode.OK, "Success",
                ResourceLoader.GetResourceText("Resources/ImageProvider/ImageModel.upload.json"), false);
            TestableWebRequestCreateFactory.GetFactory().AddRequest(expectedRequest);

            byte[] data = new byte[0];
            ImageInfo info = imgProvider.UploadImage(data, "Test Title", "test Description");
        }

        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void TestNullDataUploadImage()
        {
            ImgurAuthProvider authProvider = new AnonymousAuthenticationProvider(clientId);
            var imgProvider = new DefaultImageProvider(authProvider,
                baseTestUriTemplate);
            //var imgProvider = new DefaultImageProvider(authProvider.GetAuthorizationContext());

            var expectedRequest = new TestableWebRequest(new Uri(baseTestUriTemplate));
            expectedRequest.EnqueueResponse(HttpStatusCode.OK, "Success",
                ResourceLoader.GetResourceText("Resources/ImageProvider/ImageModel.upload.json"), false);
            TestableWebRequestCreateFactory.GetFactory().AddRequest(expectedRequest);

            ImageInfo info = imgProvider.UploadImage((byte[]) null, "Test Title", "test Description");
        }

        [Test]
        public void TestUploadImageImageTitleDescription()
        {
            ImgurAuthProvider authProvider = new AnonymousAuthenticationProvider(clientId);
            var imgProvider = new DefaultImageProvider(authProvider,
                baseTestUriTemplate);
            //var imgProvider = new DefaultImageProvider(authProvider.GetAuthorizationContext());

            var expectedRequest = new TestableWebRequest(new Uri(baseTestUriTemplate));
            expectedRequest.EnqueueResponse(HttpStatusCode.OK, "Success",
                ResourceLoader.GetResourceText("Resources/ImageProvider/ImageModel.upload.json"), false);
            TestableWebRequestCreateFactory.GetFactory().AddRequest(expectedRequest);


            byte[] data = ResourceLoader.GetResourceBytes("Resources/smiley-face.jpg");
            Image img = null;
            Bitmap bmp = null;
            using (MemoryStream ms = new MemoryStream(data))
            {
                img = Image.FromStream(ms);
                bmp = new Bitmap(img);
            }
            
            ImageInfo info = imgProvider.UploadImage(bmp, "Test Title", "test Description");

            Assert.IsNotNull(info);

            Assert.AreEqual("YXZlrwD", info.Id);
            Assert.AreEqual("Test Title", info.Title);
            Assert.AreEqual("test Description", info.Description);
            Assert.AreEqual(new DateTime(2014, 10, 15, 14, 55, 38), info.TimeStamp);
            Assert.AreEqual("image/jpeg", info.MimeType);
            Assert.AreEqual(false, info.IsAnimated);
            Assert.AreEqual(1600, info.Width);
            Assert.AreEqual(1200, info.Height);
            Assert.AreEqual(85201, info.FileSize);
            Assert.AreEqual(0, info.Views);
            Assert.AreEqual(0, info.Bandwidth);
            Assert.AreEqual(false, info.IsFavorite);
            Assert.IsNull(info.IsNSFW);
            Assert.IsNull(info.Section);
            Assert.IsNull(info.AccountUrl);
            Assert.AreEqual("R1oNYzqdLz3Q1Yw", info.DeleteHash);
            Assert.AreEqual("http://i.imgur.com/YXZlrwD.jpg", info.Link);
        }

        [Test]
        public void TestUploadImageImageTitleDescriptionAlbumId()
        {
            ImgurAuthProvider authProvider = new AnonymousAuthenticationProvider(clientId);
            var imgProvider = new DefaultImageProvider(authProvider,
                baseTestUriTemplate);
            //var imgProvider = new DefaultImageProvider(authProvider.GetAuthorizationContext());

            var expectedRequest = new TestableWebRequest(new Uri(baseTestUriTemplate));
            expectedRequest.EnqueueResponse(HttpStatusCode.OK, "Success",
                ResourceLoader.GetResourceText("Resources/ImageProvider/ImageModel.upload.json"), false);
            TestableWebRequestCreateFactory.GetFactory().AddRequest(expectedRequest);


            byte[] data = ResourceLoader.GetResourceBytes("Resources/smiley-face.jpg");
            Image img = null;
            Bitmap bmp = null;
            using (MemoryStream ms = new MemoryStream(data))
            {
                img = Image.FromStream(ms);
                bmp = new Bitmap(img);
            }

            ImageInfo info = imgProvider.UploadImage(bmp, "Test Title", "test Description", "23456");

            Assert.IsNotNull(info);

            Assert.AreEqual("YXZlrwD", info.Id);
            Assert.AreEqual("Test Title", info.Title);
            Assert.AreEqual("test Description", info.Description);
            Assert.AreEqual(new DateTime(2014, 10, 15, 14, 55, 38), info.TimeStamp);
            Assert.AreEqual("image/jpeg", info.MimeType);
            Assert.AreEqual(false, info.IsAnimated);
            Assert.AreEqual(1600, info.Width);
            Assert.AreEqual(1200, info.Height);
            Assert.AreEqual(85201, info.FileSize);
            Assert.AreEqual(0, info.Views);
            Assert.AreEqual(0, info.Bandwidth);
            Assert.AreEqual(false, info.IsFavorite);
            Assert.IsNull(info.IsNSFW);
            Assert.IsNull(info.Section);
            Assert.IsNull(info.AccountUrl);
            Assert.AreEqual("R1oNYzqdLz3Q1Yw", info.DeleteHash);
            Assert.AreEqual("http://i.imgur.com/YXZlrwD.jpg", info.Link);

            string kvTemplate = "Content-Disposition: form-data; name=\"{0}\"" + Environment.NewLine +
                                Environment.NewLine + "{1}" + Environment.NewLine;

            using (MemoryStream memoryStream = new MemoryStream(expectedRequest.GetContent()))
            {
                using (StreamReader reader = new StreamReader(memoryStream))
                {
                    string content = reader.ReadToEnd();
                    Assert.IsNotNull(content);

                    StringAssert.Contains(string.Format(kvTemplate, "album", "23456"), content);
                }
            }

        }

        [Test]
        public void TestUploadImageThrowsWebException()
        {
            ImgurAuthProvider authProvider = new AnonymousAuthenticationProvider(clientId);
            var imgProvider = new DefaultImageProvider(authProvider,
                baseTestUriTemplate);
            //var imgProvider = new DefaultImageProvider(authProvider.GetAuthorizationContext());

            var expectedRequest = new TestableWebRequest(new Uri(baseTestUriTemplate));
            expectedRequest.EnqueueResponse(HttpStatusCode.OK, "Success",
                ResourceLoader.GetResourceText("Resources/ImageProvider/ImageModel.upload.json"), true);
            TestableWebRequestCreateFactory.GetFactory().AddRequest(expectedRequest);


            byte[] data = ResourceLoader.GetResourceBytes("Resources/smiley-face.jpg");
            ImageInfo info = imgProvider.UploadImage(data, "Test Title", "test Description");

            Assert.IsNotNull(info);

            Assert.AreEqual("YXZlrwD", info.Id);
            Assert.AreEqual("Test Title", info.Title);
            Assert.AreEqual("test Description", info.Description);
            Assert.AreEqual(new DateTime(2014, 10, 15, 14, 55, 38), info.TimeStamp);
            Assert.AreEqual("image/jpeg", info.MimeType);
            Assert.AreEqual(false, info.IsAnimated);
            Assert.AreEqual(1600, info.Width);
            Assert.AreEqual(1200, info.Height);
            Assert.AreEqual(85201, info.FileSize);
            Assert.AreEqual(0, info.Views);
            Assert.AreEqual(0, info.Bandwidth);
            Assert.AreEqual(false, info.IsFavorite);
            Assert.IsNull(info.IsNSFW);
            Assert.IsNull(info.Section);
            Assert.IsNull(info.AccountUrl);
            Assert.AreEqual("R1oNYzqdLz3Q1Yw", info.DeleteHash);
            Assert.AreEqual("http://i.imgur.com/YXZlrwD.jpg", info.Link);
        }

        [Test]
        public void TestUploadImageFromImageWithNoRawFormat()
        {
            ImgurAuthProvider authProvider = new AnonymousAuthenticationProvider(clientId);
            var imgProvider = new DefaultImageProvider(authProvider,
                baseTestUriTemplate);
            //var imgProvider = new DefaultImageProvider(authProvider.GetAuthorizationContext());

            var expectedRequest = new TestableWebRequest(new Uri(baseTestUriTemplate));
            expectedRequest.EnqueueResponse(HttpStatusCode.OK, "Success",
                ResourceLoader.GetResourceText("Resources/ImageProvider/ImageModel.upload.json"), false);
            TestableWebRequestCreateFactory.GetFactory().AddRequest(expectedRequest);


            Bitmap bmp = new Bitmap(20, 20);
            ImageInfo info = imgProvider.UploadImage(bmp, "Test Title", "test Description");

            Assert.IsNotNull(info);

            Assert.AreEqual("YXZlrwD", info.Id);
            Assert.AreEqual("Test Title", info.Title);
            Assert.AreEqual("test Description", info.Description);
            Assert.AreEqual(new DateTime(2014, 10, 15, 14, 55, 38), info.TimeStamp);
            Assert.AreEqual("image/jpeg", info.MimeType);
            Assert.AreEqual(false, info.IsAnimated);
            Assert.AreEqual(1600, info.Width);
            Assert.AreEqual(1200, info.Height);
            Assert.AreEqual(85201, info.FileSize);
            Assert.AreEqual(0, info.Views);
            Assert.AreEqual(0, info.Bandwidth);
            Assert.AreEqual(false, info.IsFavorite);
            Assert.IsNull(info.IsNSFW);
            Assert.IsNull(info.Section);
            Assert.IsNull(info.AccountUrl);
            Assert.AreEqual("R1oNYzqdLz3Q1Yw", info.DeleteHash);
            Assert.AreEqual("http://i.imgur.com/YXZlrwD.jpg", info.Link);
        }
    }
}
